package 中等.队列;

/**
 * 设计实现双端队列。
 * 实现 MyCircularDeque 类:
 * MyCircularDeque(int k) ：构造函数,双端队列最大为 k 。
 * boolean insertFront()：将一个元素添加到双端队列头部。 如果操作成功返回 true ，否则返回 false 。
 * boolean insertLast() ：将一个元素添加到双端队列尾部。如果操作成功返回 true ，否则返回 false 。
 * boolean deleteFront() ：从双端队列头部删除一个元素。 如果操作成功返回 true ，否则返回 false 。
 * boolean deleteLast() ：从双端队列尾部删除一个元素。如果操作成功返回 true ，否则返回 false 。
 * int getFront() )：从双端队列头部获得一个元素。如果双端队列为空，返回 -1 。
 * int getRear() ：获得双端队列的最后一个元素。 如果双端队列为空，返回 -1 。
 * boolean isEmpty() ：若双端队列为空，则返回 true ，否则返回 false  。
 * boolean isFull() ：若双端队列满了，则返回 true ，否则返回 false 。
 * <p>
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode.cn/problems/design-circular-deque
 */
public class 设计循环双端队列_641 {

    public static void main(String[] args) {

        MyCircularDeque myCircularDeque = new MyCircularDeque(4);
        System.out.println(myCircularDeque.insertFront(9));
        System.out.println(myCircularDeque.deleteLast());
        System.out.println(myCircularDeque.getRear());

    }

    /**
     * 数组模拟
     */
    static class MyCircularDeque {

        private int[] nums;

        private int frontIdx;

        private int lastIdx;

        private int size = 0;

        public MyCircularDeque(int k) {
            nums = new int[k];
        }

        public boolean insertFront(int value) {
            if (isFull()) {
                return false;
            }
            if (isEmpty()) {
                frontIdx = 0;
                lastIdx = 0;
                nums[0] = value;
            } else {
                frontIdx--;
                frontIdx = (nums.length + frontIdx) % nums.length;
                nums[frontIdx] = value;
            }
            size++;
            return true;
        }

        public boolean insertLast(int value) {
            if (isFull()) {
                return false;
            }
            if (isEmpty()) {
                frontIdx = 0;
                lastIdx = 0;
                nums[0] = value;
            } else {
                lastIdx++;
                lastIdx = lastIdx % nums.length;
                nums[lastIdx] = value;
            }
            size++;
            return true;
        }

        public boolean deleteFront() {
            if (isEmpty()) {
                return false;
            }
            frontIdx++;
            frontIdx = frontIdx % nums.length;
            size--;
            return true;
        }

        public boolean deleteLast() {
            if (isEmpty()) {
                return false;
            }
            lastIdx--;
            lastIdx = (nums.length + lastIdx) % nums.length;
            size--;
            return true;
        }

        public int getFront() {
            if (isEmpty()) {
                return -1;
            }
            return nums[frontIdx];
        }

        public int getRear() {
            if (isEmpty()) {
                return -1;
            }
            return nums[lastIdx];
        }

        public boolean isEmpty() {
            return size == 0;
        }

        public boolean isFull() {
            return size >= nums.length;
        }
    }

}
